home *** CD-ROM | disk | FTP | other *** search
- {$A+,G-}
- { Muss mit G- kompiliert werden sonst Absturz !!!! }
- UNIT XMSSTM;
-
- INTERFACE
-
- USES Objects, Xms;
-
- TYPE
- PXmsStream = ^TXmsStream;
- TXmsStream = OBJECT (TStream)
- Handle: Word;
- Size: Longint;
- Position: Longint;
- MaxSize: WORD;
- CONSTRUCTOR Init;
- DESTRUCTOR Done; virtual;
- FUNCTION TestError(ErrCode: INTEGER; Info: WORD): BOOLEAN;
- FUNCTION GetPos: Longint; virtual;
- FUNCTION GetSize: Longint; virtual;
- PROCEDURE Read(var Buf; Count: Word); virtual;
- PROCEDURE Seek(Pos: Longint); virtual;
- PROCEDURE Truncate; virtual;
- PROCEDURE Write(var Buf; Count: Word); virtual;
- END;
-
- IMPLEMENTATION
-
-
- CONSTRUCTOR TXmsStream.Init;
- VAR ToAllocate : WORD;
-
- Procedure _Freehandle;
- begin
- Case XMS_Result of
- XMSNoHandle, { Kein Handle mehr frei }
- XMSInvHandle:; { Ungültiges Handle }
- else FreeMem(Handle);
- end;
- end;
-
- BEGIN
- Position := 0;
- Size := 0;
- Status := stInitError;
- IF (Not XMS_DriverOk) or (Xms.MaxAvail<16) or (XMS_Result <> 0)
- THEN Status := stInitError
- ELSE BEGIN
- Handle := ReserveMem(1);
- IF XMS_Result <> 0 THEN begin
- ErrorInfo := INTEGER(XMS_Result);
- _Freehandle;
- Exit;
- end ELSE Status := stOk;
- ResizeMem(16,Handle);
- MaxSize := 16;
- If XMS_Result=XMSnotimpl then
- begin
- Freemem(Handle);
- MaxSize:=XMS.MaxAvail;
- Handle:=ReserveMem(MaxSize);
- end;
- IF XMS_Result <> 0 THEN begin
- ErrorInfo := INTEGER(XMS_Result);
- _Freehandle;
- Exit;
- end ELSE Status := stOk;
- END;
- ErrorInfo := INTEGER(XMS_Result);
- END;
-
- DESTRUCTOR TXmsStream.Done;
- BEGIN
- FreeMem (Handle);
- TStream.Done;
- END;
-
- FUNCTION TXmsStream.GetPos: Longint;
- BEGIN
- GetPos := Position;
- END;
-
- FUNCTION TXmsStream.GetSize: Longint;
- BEGIN
- GetSize := Size;
- END;
-
- FUNCTION TXMSStream.TestError(ErrCode: INTEGER; Info: WORD): BOOLEAN;
- BEGIN
- TestError:=true;
- If Status<>StOk then Exit;
- IF XMS_Result <> 0
- THEN BEGIN
- Status := ErrCode;
- XMS_Result:=0;
- ErrorInfo := Info;
- END
- ELSE BEGIN
- Status := stOk;
- ErrorInfo := Info;
- TestError:=false;
- END;
- END;
-
- PROCEDURE TXmsStream.Read(var Buf; Count: Word);
- BEGIN
- IF TestError(stReadError, XMS_Result) THEN Exit;
- IF Count = 0 THEN Exit;
- MoveFromXMS(Count, Handle, Position, @Buf);
- IF TestError(stReadError, XMS_Result) THEN Exit;
- INC(Position, Count);
- IF Size < Position THEN Size := Position;
- END;
-
- PROCEDURE TXmsStream.Seek(Pos: Longint);
- BEGIN
- IF (Pos <= Size) THEN Position := Pos;
- END;
-
- PROCEDURE TXmsStream.Truncate;
- BEGIN
- Size := Position;
- (* Hier bleibt zu überlegen, ob und unter welchen Bedingungen ein *)
- (* ReAllocate durchgeführt werden soll. *)
- END;
-
- PROCEDURE TXmsStream.Write(var Buf; Count: Word);
- Var NewMaxKB :Word;
- BEGIN
- IF TestError(stWriteError, XMS_Result) THEN Exit;
- IF Count = 0 THEN Exit;
- IF Position + ((Count+1) AND $FFFE) > LONGINT(MaxSize) * 1024 THEN
- begin
- NewMaxKB:=((Position + Count - 1) DIV 1024) + 1;
- If NewMaxKB-MaxSize<16 then
- NewMaxKB:=MaxSize+16; { um mind. 16 K vergrößern }
- ResizeMem(NewMaxKB, Handle);
- If (XMS_Result=XMSoutofMem) and (NewMaxKB-MaxSize>=16) then
- begin
- Repeat
- ResizeMem(MaxSize+16,Handle);
- IF TestError(stWriteError, XMS_Result) THEN Exit;
- Inc(MaxSize,16);
- Until (MaxSize-NewMaxKB)<16;
- ResizeMem(NewMaxKB,Handle);
- end;
- IF TestError(stWriteError, XMS_Result) THEN Exit;
- MaxSize := NewMaxKB;
- END;
- MoveToXMS(Count, Handle, @Buf, Position);
- IF TestError(stWriteError, XMS_Result) THEN Exit;
- INC(Position, Count);
- IF Size < Position THEN Size := Position;
- END;
-
- END.
-
-